<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="../css/common.css" media="all" />
<link rel="stylesheet" type="text/css" href="../css/article.css" media="all" />
</head>
<body>
<div id="w3h_body">
  <div class="body_content">
    <!-- toc begin -->
    <h1 class="title">RT1012: IE6 IE7 IE8(Q) Opera 认为 'white-space:nowrap' 仅作用在纯文本内容上</h1>
<ul class="toc">
      <li><a href="#standard_reference">标准参考</a> <span>•</span></li>
      <li><a href="#description">问题描述</a> <span>•</span></li>
      <li><a href="#influence">造成的影响</a> <span>•</span></li>
      <li><a href="#impacted_browsers">受影响的浏览器</a> <span>•</span></li>
      <li><a href="#analysis_of_issues">问题分析</a> <span>•</span></li>
      <li><a href="#solutions">解决方案</a> <span>•</span></li>
      <li><a href="#see_also">参见</a></li>
    </ul>
    <!-- toc end -->
    <div id="w3h_content">
      <!-- content begin -->
      <address class="author">作者：钱宝坤</address>
    <h2 id="standard_reference">标准参考</h2>
    <p>根据 W3C CSS 2.1 规范中的描述 'white-space:nowrap' 设置的含义为：该值像 'normal' 那样合并空白，但是阻止文本内的分行。</p>
    <p>详细说明请参考：<a href="http://www.w3.org/TR/CSS21/text.html#propdef-white-space">16.6 White space: the 'white-space' property</a> </p>
    <p>替换元素是用来表示超出 CSS 格式化模型表示范围的元素，他们的共同特点是没有设置宽高的情况下拥有默认宽高。常见的有：IMG INPUT TEXTAREA IFRAME 等。</p>
    <p>详细说明请参考：<a href="http://www.w3.org/TR/CSS21/conform.html#replaced-element">replaced-element</a> </p>
    <h2 id="description">问题描述</h2>
    <p>对容器设置了 'white-space:nowrap' 特性值后，期望抑制内容换行。但是，在容器内没有文本内容仅存在行内替换元素和行内块元素时，IE6 IE7 IE8(Q) Opera 浏览器认为这些元素不是文字内容，因而抑制内容换行规则不生效。在容器布局宽度不够的情况下，行内替换元素和行内块元素将不受父容器  'white-space:nowrap' 特性值约束，产生换行。</p>

    <h2 id="influence">造成的影响</h2>
    <p>原本不希望换行的部分产生换行，导致各浏览器中小范围布局差异产生。</p>

    <h2 id="impacted_browsers">受影响的浏览器</h2>
    <table class="list">
      <tr>
        <th>IE6 IE7 IE8(Q) Opera</th>
        <td>&nbsp;</td>
      </tr>
    </table>

    <h2 id="analysis_of_issues">问题分析</h2>
    <p>根据 CSS 2.1 规范描述，  'white-space:nowrap' 值设置会阻止文本内的分行。</p>
    <pre>原文： <strong>nowrap</strong>
    This value collapses white space as for 'normal', but suppresses line breaks within <span class="hl_4">text</span>.</pre>
    <p>在说明中， <span class="hl_4">text</span> 单词存在二义性问题，他可以表示正文也可以表示为通常意义的文字内容。</p>
    <p>在实际情况中，元素内不仅只含有文本内容，还可能存在其他行内元素，如行内替换元素以及行内块元素，他们在父元素内组成了正文内容。如果规范所描述的 <span class="hl_4">text</span> 为正文含义，那么  'white-space:nowrap' 特性值设置将抑制这些元素之间产生换行。相反，'TEXT' 含义为普通文字，那么抑制换行策略将不会对这些元素生效。</p>
    <p>我们来分析以下代码：</p>
    <pre>
&lt;style&gt;
  body { font:20px/1.2 'simsun'; }
  div { width:60px; background:wheat; margin:10px 0; }
&lt;/style&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;img src="google.png" /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;input /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;input type="button" /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;input type="submit" /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;input type="file" /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;input type="checkbox" /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;input type="radio" /&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;textarea&gt;&lt;/textarea&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;select&gt;&lt;/select&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;iframe&gt;&lt;/iframe&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;button&gt;&lt;/button&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;div&gt;
  &lt;span style="white-space:nowrap;"&gt;中国字&lt;/span&gt;&lt;span style="white-space:nowrap;"&gt;&lt;span style="display:inline-block"&gt;汉字&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
</pre>

    <p>上例中，容器 DIV 元素的宽度为 60px，'white-space' 特性值是默认的 'normal' ，容器内标记紧密排列 ，没有因换行和空格产生匿名行内元素。这样容器的 'white-space:normal' 设置不会对容器内容是否换行产生影响。 </p>
    <p>容器内首个 SPAN 元素内有三个中文，每个中文的字号设置为 20px，整体宽度恰好是容器宽度 60px。这个 SPAN 元素内又设置 'white-space:nowrap' 特性值，说明其内三个文字会抑制换行产生。</p>
    <p>第二个 SPAN 元素设置  'white-space:nowrap' 特性值，其内子元素没有产生文本内容，分别是常用行内替换元素以及行内块元素。</p>
    <p>实际运行结果如下：</p>
    <table class="compare">
      <tr>
        <th>&nbsp;</th>
        <th>IE6 IE7 IE8(Q) Opera</th>
          <th>IE8(S) Firefox Chrome Safari</th>
      </tr>
      <tr>
        <th>常见行内替换元素</th>
        <td><span class="hl_3"> 产生换行</span></td>
            <td><span class="hl_4">不产生换行</span></td>
      </tr>
      <tr>
        <th>行内块元素<sup>1</sup></th>
        <td><span class="hl_3">产生换行</span></td>
          <td><span class="hl_4">不产生换行</span></td>
      </tr>
    </table>
    <p class="comment">【注】：IE6 IE7 IE8(Q) 不支持严格意义上 CSS 2.1 规范内说明的 'display:inline-block' 特性值，但是设置 ‘inline-block’ 后会触发 IE 特有的 hasLayout 特性，使行内元素具有布局块特征，这与规范描述所要达到的效果一致。关于 hasLayout 特性的详细描述请参考 MSDN ：  <a href="http://msdn.microsoft.com/en-us/library/bb250481(VS.85).aspx">"HasLayout" Overview</a> 。</p>
    <p>从表中可以看出：</p>
        <ul>
    <li><em>IE6 IE7 IE8(Q) Opera</em> 认为行内替换元素以及行内块元素不是规范内说明的文本内容，他们在父容器布局宽度不足时不受 ‘white-space:nowrap’ 特性值制约，会产生换行；</li>
    <li><em>IE8(S) Firefox Chrome Safari</em> 认为行内替换元素以及行内块元素均属于容器内正文，即使容器布局宽度不足，依然会抑制换行产生。</li>
        </ul>
    <h2 id="solutions">解决方案</h2>
    <p>如果需要使用   'white-space:nowrap' 特性值抑制内容换行，最好避免在容器内加入替换元素以及行内块元素，避免各浏览器出现对规范理解差异。</p>
    <h2 id="see_also">参见</h2>
      <h3>知识库</h3>
      <ul class="see_also">
        <li><a href="#">...</a></li>
      </ul>

      <h3>相关问题</h3>
      <ul class="see_also">
        <li><a href="#">...</a></li>
      </ul>

      <div class="appendix">
        <h2>测试环境</h2>
        <table class="list">
          <tr>
            <th>操作系统版本:</th>
            <td>Windows 7 Ultimate build 7600</td>
          </tr>
          <tr>
            <th>浏览器版本:</th>
            <td>
              IE6<br />
              IE7<br />
              IE8<br />
              Firefox 3.6.10<br />
              Chrome 8.0.552.5 dev<br />
              Safari 5.0.2<br />
              Opera 10.63
            </td>
          </tr>
          <tr>
            <th>测试页面:</th>
            <td><a href="../../tests/RT1012/replace_element_and_inline_block_element_nowrap.html">replace_element_and_inline_block_element_nowrap.html</a></td>
          </tr>
          <tr>
            <th>本文更新时间:</th>
            <td>2010-10-20</td>
          </tr>
        </table>

        <h2>关键字</h2>  
        <!-- keywords begin -->
        <p>text replace element white-space nowrap   suppresses line breaks inline-block</p>
        <!-- keywords end -->
      </div>
      <!-- content end -->
    </div>
  </div>
</div>
</body>
</html>
